package com.mini.game.api;

import com.mini.common.RedisService;
import com.mini.common.constant.RedisConstant;
import com.mini.common.util.JacksonUtil;
import com.mini.common.util.ServiceNameConstant;
import com.mini.common.vo.ReqData;
import com.mini.common.vo.ResData;
import com.mini.game.vo.ReqGetToken;
import com.mini.game.vo.ResGetAccount;
import com.mini.game.vo.ResGetToken;
import com.mini.game.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Random;
import java.util.UUID;

/**
 * @author 小鱼儿
 * @date 2020/11/17 17:00
 */
@RestController
@RequestMapping(value = "/authapi")
public class AuthApiController {
    @Autowired
    private RedisService redisService;
    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 获取账号
     */
    @RequestMapping(value = "/getaccount")
    public ResData getaccount(@RequestBody ReqData data) {
        ResGetAccount resGetAccount = new ResGetAccount();
        resGetAccount.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
        return ResData.buildResData(resGetAccount);
    }

    /**
     * 获取token
     */
    @RequestMapping(value = "/gettoken")
    public ResData gettoken(@RequestBody ReqData data) {
        ReqGetToken reqGetToken = JacksonUtil.stringToBean(data.getData(), ReqGetToken.class);
        //自己校验处理下前端随便发送的其他账号
        String userName = reqGetToken.getUserName();
        UserVo userVo = redisService.hget(RedisConstant.USER_ID, userName, UserVo.class);
        long userId = 0;
        if (userVo == null) {
            //注册下账号
            long autoId = redisService.incr(RedisConstant.INCRE_ID, 1);
            userId = buildUniqueId(autoId);
            userVo = buildUserVo(userName, userId);
            redisService.hset(RedisConstant.USER_ID, userName, JacksonUtil.toJsonString(userVo));
            redisService.hset(RedisConstant.USER_ID_2_NAME, String.valueOf(userId), userName);
        } else {
            userId = userVo.getUserId();
        }
        String tokenKey = RedisConstant.TOKEN + userId;
        String token = redisService.get(tokenKey);
        //生成token 并随机一台服务器让玩家登陆
        if (token == null) {
            token = UUID.randomUUID().toString().replaceAll("-", "");
            redisService.set(tokenKey, token, RedisConstant.TOKEN_EXPIRE_TIME);
            //token绑定服务器 玩家ID  玩家ID记录token
            List<ServiceInstance> list = discoveryClient.getInstances(ServiceNameConstant.SERVER_GAME);
            String gameServerId = list.get(new Random().nextInt(list.size())).getMetadata().get(ServiceNameConstant.SERVICE_PARA_SERVER_ID);
            redisService.set(RedisConstant.TOKEN_SERVER_ID + token, gameServerId, RedisConstant.TOKEN_EXPIRE_TIME);
            redisService.set(RedisConstant.TOKEN_USER_ID + token, String.valueOf(userId), RedisConstant.TOKEN_EXPIRE_TIME);
        }

        ResGetToken resGetToken = new ResGetToken();
        resGetToken.setToken(token);
        return ResData.buildResData(resGetToken);
    }

    public long buildUniqueId(long id) {
        return 1l << 32 | id;
    }

    public UserVo buildUserVo(String userName, long userId) {
        UserVo userVo = new UserVo();
        userVo.setUserId(userId);
        userVo.setUserName(userName);
        return userVo;
    }
}
